package kin.system.security;



import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;






import javax.inject.Inject;

import kin.bean.security.Acl;
import kin.bean.security.Permission;
import kin.bean.security.Role;
import kin.service.security.AclServiceManager;
import kin.service.security.RoleServiceManager;







import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.ConfigAttribute;
import org.springframework.security.access.SecurityConfig;
import org.springframework.security.web.FilterInvocation;
import org.springframework.security.web.access.intercept.FilterInvocationSecurityMetadataSource;


//import org.springframework.security.web.util.AntUrlPathMatcher;

import org.springframework.stereotype.Service;
import org.springframework.util.AntPathMatcher;




@Service
public class MyInvocationSecurityMetadataSourceService implements
		FilterInvocationSecurityMetadataSource {

	private AntPathMatcher urlMatcher = new AntPathMatcher();
	private static Map<String, Collection<ConfigAttribute>> resourceMap = null;

	//private ButtonServiceManager buttonServiceManager;
	
	private RoleServiceManager roleServiceManager;
	
	private AclServiceManager aclServiceManager;

	//private ModuleServiceManager moduleServiceManager;


	public MyInvocationSecurityMetadataSourceService(
			RoleServiceManager roleServiceManager,
			AclServiceManager aclServiceManager
			//ModuleServiceManager moduleServiceManager,
			//ButtonServiceManager buttonServiceManager
			) {
		System.out.println("aaaa---------------");
		this.roleServiceManager = roleServiceManager;
		this.aclServiceManager = aclServiceManager;
		//this.moduleServiceManager = moduleServiceManager;
		//this.buttonServiceManager = buttonServiceManager;
		
		loadResourceDefine();
	}

	/*private void scanModuleByPackage(ClassPathScanningCandidateComponentProvider scanner,String packageName) throws Exception {
		for (BeanDefinition beanDefinition : scanner.findCandidateComponents(packageName)) {
			Class cla = Class.forName(beanDefinition.getBeanClassName());
			if (cla.isAnnotationPresent(RequestMapping.class)&& cla.isAnnotationPresent(kin.annotation.system.Module.class)) {
				kin.annotation.system.Module pm = (kin.annotation.system.Module) cla.getAnnotation(kin.annotation.system.Module.class);
				RequestMapping r = (RequestMapping) cla.getAnnotation(RequestMapping.class);
				String path = r.value()[0];
				Module mp = new Module();
				mp.setClassName(cla.getName());
				mp.setModule_url(path);
				mp.setLeaf(false);
				mp.setRenderToNAV(pm.renderToNAV());
				mp.setLabel(pm.label());
				this.moduleServiceManager.add(mp);
				Method[] methods = cla.getDeclaredMethods();
				for (int i = 0; i < methods.length; i++) {
					Method method = methods[i];
					boolean b = method.isAnnotationPresent(RequestMapping.class)&& method.isAnnotationPresent(kin.annotation.system.Module.class);
					if (b) {

						RequestMapping racc = method.getAnnotation(RequestMapping.class);
						kin.annotation.system.Module pc = (kin.annotation.system.Module) method.getAnnotation(kin.annotation.system.Module.class);

						Module module = new Module();
						module.setLabel(pc.label());
						String ppa = racc.value()[0].split("/")[1];
						module.setModule_url(path + "/" + ppa);
						String meth = "GET";
						if (racc.method().length > 0) {
							meth = (racc.method()[0].name()).toString();
						}
						module.setClassMethodName(method.getName());
						module.setClassName(cla.getName());
						module.setMethod(meth);
						module.setParent(mp);
						module.setLeaf(true);

						module.setSimpleClassName(path.split("/")[1]);
						if ("".equals(pc.view())) {
							module.setView(ppa);
						} else {
							module.setView(pc.view());
						}
						module.setRenderToNAV(pc.renderToNAV());
						if (method.isAnnotationPresent(kin.annotation.system.Button.class)) {

							kin.annotation.system.Button button = method.getAnnotation(kin.annotation.system.Button.class);
							Button btn = new Button();
							btn.setLabel(button.label());
							btn.setSort(btn.getSort());
							btn.setAction(ppa);
							btn.setMethod(meth);
							btn.setRenderToActionColumn(button.renderToActionColumn());
							btn.setRenderToList(button.renderToList());
							btn.setTargetName(module.getSimpleClassName());
							btn.setUrl(module.getModule_url());
							this.buttonServiceManager.add(btn);
						}

						this.moduleServiceManager.add(module);

					}
				}
			}
		}
	}*/

	private void loadResourceDefine() {
		
		if (resourceMap == null) {
			resourceMap = new HashMap<String, Collection<ConfigAttribute>>();
		}
		List<Acl> acls = this.aclServiceManager.findAll();
		for (Acl acl : acls) {

			if (acl.getAclId().getPrincipalType().equals(Acl.TYPE_ROLE)) {
				String ur = acl.getAclId().getModule().getModule_url();
				int id = acl.getAclId().getPrincipalId();
				System.out.println("acl.getAclId():" + ur);
				Role r = this.roleServiceManager.get(id);
				String rol = r.getRole_name();
				/* resourceMap.put(ur, new SecurityConfig(rol)); */
				/*
				 * Collection<ConfigAttribute> pc= resourceMap.get(ur);
				 * ConfigAttribute pca = new SecurityConfig("Anonymous");
				 * if(pc==null){ System.out.println("in----pppppp----"); pc=new
				 * HashSet<ConfigAttribute>(); } pc.add(pca);
				 * 
				 * resourceMap.put(ur, pc);
				 */

				if (acl.getPermission(Permission.Create) == 1) {
					Collection<ConfigAttribute> c = resourceMap
							.get(ur + "/add");

					ConfigAttribute ca = new SecurityConfig(rol);
					if (c == null) {
						System.out.println("in--------");
						c = new HashSet<ConfigAttribute>();
					}
					c.add(ca);
					resourceMap.put(ur, c);
					resourceMap.put(ur + "/add", c);
					System.out.println("cas:" + ur + "/add" + ",role" + rol);
				}
				if (acl.getPermission(Permission.Read) == 1) {
					Collection<ConfigAttribute> c = resourceMap.get(ur
							+ "/list");

					ConfigAttribute ca = new SecurityConfig(rol);
					if (c == null) {
						c = new HashSet<ConfigAttribute>();
					}
					c.add(ca);
					resourceMap.put(ur + "/list", c);
					resourceMap.put(ur, c);
					System.out.println("cas:" + ur + "/list" + ",role" + rol);
				}
				if (acl.getPermission(Permission.Update) == 1) {
					Collection<ConfigAttribute> c = resourceMap.get(ur
							+ "/update");

					ConfigAttribute ca = new SecurityConfig(rol);
					if (c == null) {
						c = new HashSet<ConfigAttribute>();
					}
					c.add(ca);
					resourceMap.put(ur + "/update", c);
					resourceMap.put(ur, c);
					System.out.println("cas:" + ur + "/update" + ",role" + rol);
				}

				if (acl.getPermission(Permission.Delete) == 1) {
					Collection<ConfigAttribute> c = resourceMap.get(ur
							+ "/delete");

					ConfigAttribute ca = new SecurityConfig(rol);
					if (c == null) {
						c = new HashSet<ConfigAttribute>();
					}
					c.add(ca);
					resourceMap.put(ur, c);
					resourceMap.put(ur + "/delete", c);
					System.out.println("cas:" + ur + "/delete" + ",role" + rol);
				}
				if (acl.getPermission(Permission.Upload) == 1) {
					Collection<ConfigAttribute> c = resourceMap.get(ur
							+ "/upload");

					ConfigAttribute ca = new SecurityConfig(rol);
					if (c == null) {
						c = new HashSet<ConfigAttribute>();
					}
					c.add(ca);
					resourceMap.put(ur, c);
					resourceMap.put(ur + "/upload", c);
					System.out.println("cas:" + ur + "/upload" + ",role" + rol);
				}
				if (acl.getPermission(Permission.Download) == 1) {
					Collection<ConfigAttribute> c = resourceMap.get(ur
							+ "/download");

					ConfigAttribute ca = new SecurityConfig(rol);
					if (c == null) {
						c = new HashSet<ConfigAttribute>();
					}
					c.add(ca);
					resourceMap.put(ur, c);
					resourceMap.put(ur + "/download", c);
					System.out.println("cas:" + ur + "/download" + ",role"
							+ rol);
				}
				if (acl.getPermission(Permission.serach) == 1) {
					Collection<ConfigAttribute> c = resourceMap.get(ur
							+ "/serach");

					ConfigAttribute ca = new SecurityConfig(rol);
					if (c == null) {
						c = new HashSet<ConfigAttribute>();
					}
					c.add(ca);
					resourceMap.put(ur, c);
					resourceMap.put(ur + "/serach", c);
					System.out.println("cas:" + ur + "/serach" + ",role" + rol);
				}
			}

		}

		/*
		 * String localAntPath8 = "/**"; Set<ConfigAttribute> configList8 = new
		 * HashSet<ConfigAttribute>(); configList8.add(new
		 * SecurityConfig("ROLE_ALL_LOGON")); ConfigAttribute cad8 = new
		 * ConfigAttribute(configList8); RequestKey requestKey8 = new
		 * RequestKey(localAntPath8);
		 */
		Map<String, Collection<ConfigAttribute>> resource = resourceMap;
		System.out.println("resourceMap:" + resource);

	}

	/*
	 * private void loadResourceDefine() {
	 * 
	 * if (resourceMap == null) { resourceMap = new HashMap<String,
	 * Collection<ConfigAttribute>>(); } Collection<ConfigAttribute> atts = new
	 * ArrayList<ConfigAttribute>(); ConfigAttribute ca = new
	 * SecurityConfig("ROLE_Admin"); atts.add(ca);
	 * resourceMap.put("/user/index", atts);
	 * 
	 * resourceMap.put("/favicon.ico", atts);
	 * 
	 * }
	 */

	public Collection<ConfigAttribute> getAttributes(Object object)
			throws IllegalArgumentException {
		// guess object is a URL.
		String url = ((FilterInvocation) object).getRequestUrl();
		if (resourceMap == null) {
			loadResourceDefine();
		}

		Iterator<String> ite = resourceMap.keySet().iterator();
		while (ite.hasNext()) {
			String resURL = ite.next();
			System.out.println("url:" + url);
			System.out.println("resURL:" + resURL);
			if (urlMatcher.match(url, resURL)) {
				return resourceMap.get(resURL);
			}
		}

		return null;
	}
	
	

	public Collection<ConfigAttribute> getAllConfigAttributes() {

		/*
		 * Set<ConfigAttribute> allAttributes = new HashSet<ConfigAttribute>();
		 * 
		 * for (Map.Entry<String, Collection<ConfigAttribute>> entry :
		 * resourceMap.entrySet()) { allAttributes.addAll(entry.getValue()); }
		 */

		return null;
	}

	public boolean supports(Class<?> clazz) {
		// TODO Auto-generated method stub
		return true;
	}

	public RoleServiceManager getRoleServiceManager() {
		return roleServiceManager;
	}

	public void setRoleServiceManager(RoleServiceManager roleServiceManager) {
		this.roleServiceManager = roleServiceManager;
	}

	public AclServiceManager getAclServiceManager() {
		return aclServiceManager;
	}

	public void setAclServiceManager(AclServiceManager aclServiceManager) {
		this.aclServiceManager = aclServiceManager;
	}

	/*public ModuleServiceManager getModuleServiceManager() {
		return moduleServiceManager;
	}

	public void setModuleServiceManager(
			ModuleServiceManager moduleServiceManager) {
		this.moduleServiceManager = moduleServiceManager;
	}*/

	public static Map<String, Collection<ConfigAttribute>> getResourceMap() {
		return resourceMap;
	}

	public static void setResourceMap(
			Map<String, Collection<ConfigAttribute>> resourceMap) {
		MyInvocationSecurityMetadataSourceService.resourceMap = resourceMap;
	}

	/*public ButtonServiceManager getButtonServiceManager() {
		return buttonServiceManager;
	}

	public void setButtonServiceManager(
			ButtonServiceManager buttonServiceManager) {
		this.buttonServiceManager = buttonServiceManager;
	}*/

	

	
	
	
	
}
